package com.com.effectivejava.objectcreation;

import java.io.Serializable;
import java.util.logging.Logger;

/**
 * Created by pankaj on 7/6/14.
 */

class SingletonClass implements Serializable {
    static Logger logger = Logger.getLogger(SingletonClass.class.getName());

    static {
        logger.setParent(Logger.getLogger(SingletonClass.class.getPackage().getName()));
    }

    //Since it is static, It is ensured that instance will be initialized once class is loaded into memory.
    //instance will be created from with in class because of private constructor.
    //No synchronization is needed in this approach to create a single-instance(singleton) class.
    public static final SingletonClass INSTANCE = new SingletonClass();


    //Following field causes stack-over flow error.
    //public final SingletonClass instance2 = new SingletonClass();

    //Private constructor ensures that it will not be called from outside the class.
    private SingletonClass() {
        logger.info("Private Constructor called!!!");
    }

    //readResolve method to preserve singleton property.
    public Object readResolve(){
        // THIS class does implement serializable but we want it to be singleton too.
        // Declare all instance fields transient. for now it does not have any.
        // This method returns only instance for the class.
        return INSTANCE;
    }


}

//Best way to generate Singleton. came after 1.5
enum TrueSingleton{
    INSTANCE;

    //other methods go here ....
}

public class SingletonClassClient{
    static Logger logger = Logger.getLogger(SingletonClassClient.class.getName());

    static {
        logger.setParent(Logger.getLogger(SingletonClassClient.class.getPackage().getName()));
    }
    public static void main(String... a)
    {/*
        for(int i=0;i<10;i++){
            System.out.println(SingletonClass.INSTANCE);
        }
        for(int i=0;i<10;i++){
            //System.out.println( new SingletonClass().instance);
            //final variable cannot be reinitialize.
            //new SingletonClass().instance=new SingletonClass();
        }*/
        logger.info(SingletonClass.logger.getName());

        logger.info(SingletonClass.INSTANCE.toString());
        logger.info(SingletonClass.INSTANCE.toString());
    }
}




